/*****************************************************************************
* AudioBrowserActivity.java
*****************************************************************************
* Copyright © 2011-2012 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
package org.videolan.vlc.gui.audio;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.videolan.libvlc.Media;
import org.videolan.vlc.AudioServiceController;
import org.videolan.vlc.MediaLibrary;
import org.videolan.vlc.Util;
import org.videolan.vlc.VlcRunnable;
import org.videolan.vlc.WeakHandler;
import org.videolan.vlc.gui.CommonDialogs;
import org.videolan.vlc.gui.MainActivity;
import org.videolan.vlc.widget.FlingViewGroup;
import org.videolan.vlc.widget.FlingViewGroup.ViewSwitchListener;
import org.videolan.vlc.widget.HeaderScrollView;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.PopupMenu.OnMenuItemClickListener;
import com.actionbarsherlock.app.SherlockFragment;
import org.tribler.triblersvod.gui.R;
public class AudioBrowserFragment extends SherlockFragment {
public final static String TAG = "VLC/AudioBrowserFragment";
private FlingViewGroup mFlingViewGroup;
private int mFlingViewPosition = 0;
private HeaderScrollView mHeader;
private AudioServiceController mAudioController;
private MediaLibrary mMediaLibrary;
private AudioBrowserListAdapter mSongsAdapter;
private AudioBrowserListAdapter mArtistsAdapter;
private AudioBrowserListAdapter mAlbumsAdapter;
private AudioBrowserListAdapter mGenresAdapter;
public final static int MODE_TOTAL = 4; // Number of audio browser modes
public final static int MODE_ARTIST = 0;
public final static int MODE_ALBUM = 1;
public final static int MODE_SONG = 2;
public final static int MODE_GENRE = 3;
/* All subclasses of Fragment must include a public empty constructor. */
public AudioBrowserFragment() { }
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAudioController = AudioServiceController.getInstance();
mMediaLibrary = MediaLibrary.getInstance(getActivity());
mSongsAdapter = new AudioBrowserListAdapter(getActivity(), AudioBrowserListAdapter.ITEM_WITH_COVER);
mArtistsAdapter = new AudioBrowserListAdapter(getActivity(), AudioBrowserListAdapter.ITEM_WITH_COVER);
mAlbumsAdapter = new AudioBrowserListAdapter(getActivity(), AudioBrowserListAdapter.ITEM_WITH_COVER);
mGenresAdapter = new AudioBrowserListAdapter(getActivity(), AudioBrowserListAdapter.ITEM_WITHOUT_COVER);
mSongsAdapter.setContextPopupMenuListener(mContextPopupMenuListener);
mArtistsAdapter.setContextPopupMenuListener(mContextPopupMenuListener);
mAlbumsAdapter.setContextPopupMenuListener(mContextPopupMenuListener);
mGenresAdapter.setContextPopupMenuListener(mContextPopupMenuListener);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
getSherlockActivity().getSupportActionBar().setTitle(R.string.audio);
View v = inflater.inflate(R.layout.audio_browser, container, false);
mFlingViewGroup = (FlingViewGroup)v.findViewById(R.id.content);
mFlingViewGroup.setOnViewSwitchedListener(mViewSwitchListener);
mHeader = (HeaderScrollView)v.findViewById(R.id.header);
mHeader.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent e) {
// prevent the user from scrolling the header
return true;
}
});
ListView songsList = (ListView)v.findViewById(R.id.songs_list);
ListView artistList = (ListView)v.findViewById(R.id.artists_list);
ListView albumList = (ListView)v.findViewById(R.id.albums_list);
ListView genreList = (ListView)v.findViewById(R.id.genres_list);
songsList.setAdapter(mSongsAdapter);
artistList.setAdapter(mArtistsAdapter);
albumList.setAdapter(mAlbumsAdapter);
genreList.setAdapter(mGenresAdapter);
songsList.setOnItemClickListener(songListener);
artistList.setOnItemClickListener(artistListListener);
albumList.setOnItemClickListener(albumListListener);
genreList.setOnItemClickListener(genreListListener);
registerForContextMenu(songsList);
registerForContextMenu(artistList);
registerForContextMenu(albumList);
registerForContextMenu(genreList);
return v;
}
@Override
public void onPause() {
super.onPause();
mMediaLibrary.removeUpdateHandler(mHandler);
}
@Override
public void onResume() {
super.onResume();
mFlingViewGroup.setPosition(mFlingViewPosition);
mHeader.highlightTab(-1, mFlingViewPosition);
mHeader.scroll(mFlingViewPosition / 3.f);
updateLists();
mMediaLibrary.addUpdateHandler(mHandler);
}
OnItemClickListener songListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> av, View v, int p, long id) {
ArrayList<String> mediaLocation = mSongsAdapter.getLocations(p);
mAudioController.load(mediaLocation, 0);
}
};
OnItemClickListener artistListListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> av, View v, int p, long id) {
ArrayList<Media> mediaList = mArtistsAdapter.getMedia(p);
MainActivity activity = (MainActivity)getActivity();
AudioAlbumsSongsFragment frag = (AudioAlbumsSongsFragment)activity.showNewFragment("albumsSongs");
frag.setMediaList(mediaList, mediaList.get(0).getArtist());
}
};
OnItemClickListener albumListListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> av, View v, int p, long id) {
ArrayList<String> mediaLocation = mAlbumsAdapter.getLocations(p);
mAudioController.load(mediaLocation, 0);
}
};
OnItemClickListener genreListListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> av, View v, int p, long id) {
ArrayList<Media> mediaList = mGenresAdapter.getMedia(p);
MainActivity activity = (MainActivity)getActivity();
AudioAlbumsSongsFragment frag = (AudioAlbumsSongsFragment)activity.showNewFragment("albumsSongs");
frag.setMediaList(mediaList, mediaList.get(0).getGenre());
}
};
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.audio_list_browser, menu);
setContextMenuItems(menu, v);
}
private void setContextMenuItems(Menu menu, View v) {
if (v.getId() != R.id.songs_list) {
menu.setGroupVisible(R.id.songs_view_only, false);
menu.setGroupVisible(R.id.phone_only, false);
}
if (!Util.isPhone())
menu.setGroupVisible(R.id.phone_only, false);
}
@Override
public boolean onContextItemSelected(MenuItem menu) {
if(!getUserVisibleHint())
return super.onContextItemSelected(menu);
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menu.getMenuInfo();
if (info != null && handleContextItemSelected(menu, info.position))
return true;
return super.onContextItemSelected(menu);
}
private boolean handleContextItemSelected(MenuItem item, int position) {
ContextMenuInfo menuInfo = item.getMenuInfo();
int startPosition;
int groupPosition;
List<String> medias;
int id = item.getItemId();
boolean useAllItems = id == R.id.audio_list_browser_play_all;
boolean append = id == R.id.audio_list_browser_append;
if (ExpandableListContextMenuInfo.class.isInstance(menuInfo)) {
ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuInfo;
groupPosition = ExpandableListView.getPackedPositionGroup(info.packedPosition);
}
else
groupPosition = position;
if (id == R.id.audio_list_browser_delete) {
AlertDialog alertDialog = CommonDialogs.deleteMedia(
getActivity(),
mSongsAdapter.getLocations(groupPosition).get(0),
new VlcRunnable(mSongsAdapter.getItem(groupPosition)) {
@Override
public void run(Object o) {
Media aMedia = (Media) o;
mMediaLibrary.getMediaItems().remove(aMedia);
updateLists();
}
});
alertDialog.show();
return true;
}
if (id == R.id.audio_list_browser_set_song) {
//AudioUtil.setRingtone(mSongsAdapter.getItem(groupPosition),getActivity());
return true;
}
if (useAllItems) {
medias = new ArrayList<String>();
startPosition = mSongsAdapter.getListWithPosition(medias, groupPosition);
}
else {
startPosition = 0;
switch (mFlingViewGroup.getPosition())
{
case MODE_SONG:
medias = mSongsAdapter.getLocations(groupPosition);
break;
case MODE_ARTIST:
medias = mArtistsAdapter.getLocations(groupPosition);
break;
case MODE_ALBUM:
medias = mArtistsAdapter.getLocations(groupPosition);
break;
case MODE_GENRE:
medias = mGenresAdapter.getLocations(groupPosition);
break;
default:
return true;
}
}
if (append)
mAudioController.append(medias);
else
mAudioController.load(medias, startPosition);
return super.onContextItemSelected(item);
}
@Override
public void onDestroy() {
super.onDestroy();
mSongsAdapter.clear();
mArtistsAdapter.clear();
mAlbumsAdapter.clear();
mGenresAdapter.clear();
}
private final ViewSwitchListener mViewSwitchListener = new ViewSwitchListener() {
@Override
public void onSwitching(float progress) {
mHeader.scroll(progress);
}
@Override
public void onSwitched(int position) {
mHeader.highlightTab(mFlingViewPosition, position);
mFlingViewPosition = position;
}
@Override
public void onTouchDown() {}
@Override
public void onTouchUp() {}
};
/**
* Handle changes on the list
*/
private Handler mHandler = new AudioBrowserHandler(this);
private static class AudioBrowserHandler extends WeakHandler<AudioBrowserFragment> {
public AudioBrowserHandler(AudioBrowserFragment owner) {
super(owner);
}
@Override
public void handleMessage(Message msg) {
AudioBrowserFragment fragment = getOwner();
if(fragment == null) return;
switch (msg.what) {
case MediaLibrary.MEDIA_ITEMS_UPDATED:
fragment.updateLists();
break;
}
}
};
private void updateLists() {
List<Media> audioList = MediaLibrary.getInstance(getActivity()).getAudioItems();
mSongsAdapter.clear();
mArtistsAdapter.clear();
mAlbumsAdapter.clear();
mGenresAdapter.clear();
Collections.sort(audioList, MediaComparators.byName);
for (int i = 0; i < audioList.size(); i++) {
Media media = audioList.get(i);
mSongsAdapter.add(media.getTitle(), media.getArtist(), media);
}
Collections.sort(audioList, MediaComparators.byArtist);
for (int i = 0; i < audioList.size(); i++) {
Media media = audioList.get(i);
mArtistsAdapter.add(media.getArtist(), null, media);
}
mArtistsAdapter.addLeterSeparators();
Collections.sort(audioList, MediaComparators.byAlbum);
for (int i = 0; i < audioList.size(); i++) {
Media media = audioList.get(i);
mAlbumsAdapter.add(media.getAlbum(), media.getArtist(), media);
}
mAlbumsAdapter.addLeterSeparators();
Collections.sort(audioList, MediaComparators.byGenre);
for (int i = 0; i < audioList.size(); i++) {
Media media = audioList.get(i);
mGenresAdapter.add(media.getGenre(), null, media);
}
mGenresAdapter.addLeterSeparators();
mSongsAdapter.notifyDataSetChanged();
mArtistsAdapter.notifyDataSetChanged();
mAlbumsAdapter.notifyDataSetChanged();
mGenresAdapter.notifyDataSetChanged();
}
AudioBrowserListAdapter.ContextPopupMenuListener mContextPopupMenuListener
= new AudioBrowserListAdapter.ContextPopupMenuListener() {
@Override
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onPopupMenu(View anchor, final int position) {
if (!Util.isHoneycombOrLater()) {
// Call the "classic" context menu
anchor.performLongClick();
return;
}
PopupMenu popupMenu = new PopupMenu(getActivity(), anchor);
popupMenu.getMenuInflater().inflate(R.menu.audio_list_browser, popupMenu.getMenu());
setContextMenuItems(popupMenu.getMenu(), anchor);
popupMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
return handleContextItemSelected(item, position);
}
});
popupMenu.show();
}
};
}